package com.cxd.app.service;

import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.cxd.app.entity.AccountBalance;
import com.cxd.app.entity.AppBankCard;
import com.cxd.app.entity.AppProfit;
import com.cxd.app.entity.base.BankCardBase;
import com.cxd.app.entity.base.ConfigBase;
import com.cxd.app.entity.base.DictBase;
import com.cxd.app.entity.base.InvestRepayBase;
import com.cxd.app.entity.base.LoanBase;
import com.cxd.app.entity.base.RechargeBase;
import com.cxd.app.entity.base.TrusteeshipOperationBase;
import com.cxd.app.entity.base.UserBase;
import com.cxd.app.entity.base.UserBillBase;
import com.cxd.app.entity.base.WithdrawCashBase;
import com.cxd.app.mapper.read.RInvestMapper;
import com.cxd.app.mapper.read.RLoanMapper;
import com.cxd.app.mapper.read.RMyAccountMapper;
import com.cxd.app.service.tools.YeePayParams;
import com.cxd.base.common.constants.BankCardConstants;
import com.cxd.base.common.constants.Constants;
import com.cxd.base.common.constants.UserBillConstants;
import com.cxd.base.common.constants.YeePayConstants;
import com.cxd.base.common.exception.CxdException;
import com.cxd.base.page.PageUtil;
import com.cxd.base.util.ArithUtil;
import com.cxd.base.util.BeanTools;
import com.cxd.base.util.HtmlElementUtil;
import com.cxd.base.util.IdGenerator;
import com.cxd.base.util.MapUtil;
import com.cxd.base.util.NumberUtil;
import com.cxd.base.util.ParamUtil;
import com.cxd.base.util.wtj.BUtils;
import com.cxd.base.util.yeepay.Dom4jUtil;
import com.cxd.message.exception.AppConstants;
import com.cxd.message.exception.CFCASignUtil;
import com.cxd.message.exception.InsufficientBalance;
import com.cxd.message.exception.TrusteeshipConstants;

/**
 * <一句话功能简述> <功能详细描述>
 * 
 * @author wtj
 * @date 2015年12月5日 下午3:13:09
 * @company CXD
 * @version [Copyright (c) 2015 V001]
 */
@Service("myaccountService")
public class MyAccountService {
	@Resource
	BeanTools bt;

	@Resource
	RLoanMapper rloanMapper;

	@Resource
	RInvestMapper rinvestMapper;

	@Resource
	RMyAccountMapper rmyAccountMapper;

	@Resource
	DictService dictService;

	@Resource
	RechargeService rechargeService;
	
	@Resource 
	WithdrawCashService withdrawCashService;
	
	@Resource 
	UserService userService;
	
	@Resource
	public BeanService beanService;
	
	private static final Logger log = Logger.getLogger(MyAccountService.class);
	/**
	 * 获取用户余额
	 * @author wtj
	 * @date 2015年12月14日上午10:25:13
	 * @param json
	 * @param value
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public void accountBalance(JSONObject json, String value)
			throws InstantiationException, IllegalAccessException {
		Map<String, String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		ParamUtil.notNullParam("用户名:" + userId);
		AccountBalance accountBalance = new AccountBalance();
		UserBillBase ubs = accountBalanceBase(json,userId);
		accountBalance.setBalance(ubs==null?"0":NumberUtil.getNumber(ubs.getBalance()+ubs.getFrozenMoney()+getReceivableCorpus(userId)+getReceivableInterest(userId)));
		accountBalance.setBalanceAvaliable(ubs==null?"0":NumberUtil.getNumber(ubs.getBalance()));
		accountBalance.setCollectCorpus(NumberUtil.getNumber(getReceivableCorpus(userId)));
		accountBalance.setCollectInterest(NumberUtil.getNumber(getReceivableInterest(userId)));
		accountBalance.setCollectProfit(NumberUtil.getNumber(getReceivedInterest(userId)+getReceivableInterest(userId)));
		accountBalance.setFreezeAmount(ubs==null?"0":NumberUtil.getNumber(ubs.getFrozenMoney()));
		accountBalance.setReceivedCorpus(NumberUtil.getNumber(getReceivedCorpus(userId)));
		accountBalance.setReceviedInterest(NumberUtil.getNumber(getReceivedInterest(userId)));
		accountBalance.setTotalInvestAmount(NumberUtil.getNumber(getReceivedCorpus(userId)+getReceivableCorpus(userId)));
		accountBalance.setCollectCorpusAndInterest(NumberUtil.getNumber(getReceivableCorpus(userId)+getReceivableInterest(userId)));
		accountBalance.setTotalMoney(ubs==null?"0":NumberUtil.getNumber(ubs.getBalance()+ubs.getFrozenMoney()+getReceivableCorpus(userId)+getReceivableInterest(userId)));
		json.put("result", accountBalance);
//		json.putAll(BUtils.beanToMap(accountBalanceBase(json, userId)));
	}

	/**
	 * 应收（待收）本金
	 * @return
	 */
	private double getReceivableCorpus(String userId) {
		String sql = "SELECT sum(CORPUS) as countNum FROM INVEST_REPAY ir INNER JOIN INVEST inv on ir.INVEST_ID = inv.ID WHERE inv.USER_ID='"+userId+"' and inv.`status` ='repaying'";
		List<Map<String,Object>> result = bt.queryListMap(sql);
		double money = 0;
		if (result != null && result.get(0) != null) {
			money = (Double) result.get(0).get("countNum");
		}
		return money;
	}
	/**
	 * 账户余额查询
	 * 
	 * @author wtj
	 * @date 2015年12月5日下午3:13:38
	 * @param json
	 * @param value
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public UserBillBase accountBalanceBase(JSONObject json, String userId)
			throws InstantiationException, IllegalAccessException {
		return getLastestBill(userId);
	}

	/**
	 * 绑卡查询
	 * 
	 * @author wtj
	 * @date 2015年12月10日上午9:59:38
	 * @param json
	 * @param value
	 * @return
	 */
	public JSONObject bindCardQuery(JSONObject json, String value) {
		Map<String, String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		ParamUtil.notNullParam("用户名:" + userId);
		// 获取该账户绑定的状态为不是”已删除“状态的银行卡(易宝只能绑定一张)
		String sql = "SELECT ID,NAME,BANK,BANK_AREA,CARD_NO,TIME,STATUS,USER_ID,BINDINGPRICE,ACCOUNT_NAME,BANK_CARD_TYPE,BANK_CITY"
				+ " BANK_NO,BANK_PROVINCE,BINDING_PRICE,BANK_ADDRESS,BANK_SERVICE_TYPE  "
				+ " FROM BANK_CARD where user_id='"
				+ userId
				+ "' and status != '"
				+ BankCardConstants.BankCardStatus.DELETED+ "' order by time desc limit 0,1";
		BankCardBase bean = bt.queryBean(sql, BankCardBase.class);
		if (bean == null) {
			json.put("status", 200);
			json.put("msg", "用户没有绑卡记录");
			json.put("result",new String[]{});
			return json;
		}
		UserBase userBean = beanService.getUserById(userId);
		List<AppBankCard> appList = new ArrayList<AppBankCard>();
		AppBankCard appCard = null;
			appCard = new AppBankCard();
			appCard.setCardNo(bean.getCardNo());
			appCard.setBankName(bean.getBank());
			appCard.setRealname(userBean.getRealname());
			appCard.setIdCard(userBean.getIdCard());
			appCard.setIconUrl(MessageFormat.format(AppConstants.PublicConstants.BANK_CARD_URL, YeePayParams.getBankCode(bean.getBankNo(),bean.getBank())));
			appCard.setStatus(bean.getStatus().equals("VERIFIED") ? "绑卡成功": "审核中");
			appList.add(appCard);
		json.put("result", appList.size()==0?new String[]{}:appList);
		return json;
	}

	/**
	 * 获取用户余额
	 * @author wtj
	 * @date 2015年12月11日下午3:35:14
	 * @param userId
	 * @return
	 */
	public double getUserBalance(String userId) {
		UserBillBase ub = getLastestBill(userId);
		return ub == null ? 0D : ub.getBalance();
	}

	/**
	 * 获取最后记录
	 * 
	 * @author wtj
	 * @date 2015年12月5日下午3:38:22
	 * @param userId
	 * @return
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public UserBillBase getLastestBill(String userId) {
		UserBillBase ubBase = bt.queryBean(
				"SELECT * FROM USER_BILL WHERE USER_ID = '" + userId
						+ "' ORDER BY SEQ_NUM desc LIMIT 0,1",
				UserBillBase.class);
		if (ubBase != null) {
			if (ubBase.getBalance() == null || ubBase.getFrozenMoney() == null) {
				if (ubBase.getBalance() == null) {
					double freeze = getSumByType(userId,
							UserBillConstants.Type.FREEZE);
					double transferIntoBalance = getSumByType(userId,
							UserBillConstants.Type.TI_BALANCE);
					double transferOutFromBalance = getSumByType(userId,
							UserBillConstants.Type.TO_BALANCE);
					double unfreeze = getSumByType(userId,
							UserBillConstants.Type.UNFREEZE);
					ubBase.setBalance(ArithUtil.add(ArithUtil.sub(ArithUtil
							.sub(transferIntoBalance, transferOutFromBalance),
							freeze), unfreeze));
				}
				if (ubBase.getFrozenMoney() == null) {
					double freeze = getSumByType(userId,
							UserBillConstants.Type.FREEZE);
					double transferOutFromFrozen = getSumByType(userId,
							UserBillConstants.Type.TO_FROZEN);
					double unfreeze = getSumByType(userId,
							UserBillConstants.Type.UNFREEZE);
					ubBase.setFrozenMoney(ArithUtil.sub(
							ArithUtil.sub(freeze, unfreeze),
							transferOutFromFrozen));
				}
				bt.modify(ubBase);
			}
			return ubBase;
		}
		return null;
	}

	/**
	 * 冻结金额
	 * 
	 * @param userId
	 *            用户的id
	 * @param money
	 *            金额
	 * @param operatorInfo
	 *            资金转移的操作类型
	 * @param operatorDetail
	 *            资金转移的详述
	 * @throws InsufficientBalance
	 *             抛出异常 余额不足以支付保证金
	 * @throws IllegalAccessException
	 * @throws InstantiationException
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public void freezeMoney(String userId, double money, String operatorInfo,
			String operatorDetail) throws InsufficientBalance {
		if (money < 0) {
			throw new RuntimeException("money cannot be less than zero!");
		}
		UserBillBase ibLastest = getLastestBill(userId);
		UserBillBase ib = new UserBillBase();
		double balance = getUserBalance(userId);
		if (balance < money) {
			throw new InsufficientBalance("freeze money:" + money
					+ ", balance:" + balance);
		} else {
			ib.setId(IdGenerator.randomUUID());
			ib.setMoney(money);
			ib.setTime(new Date());
			ib.setDetail(operatorDetail);
			ib.setType(UserBillConstants.Type.FREEZE);
			ib.setTypeInfo(operatorInfo);
			ib.setUserId(userId);
			if (ibLastest == null) {
				ib.setSeqNum(1);
				// 余额=0
				ib.setBalance(0D);
				// 最新冻结金额=0
				ib.setFrozenMoney(0D);
			} else {
				ib.setSeqNum(ibLastest.getSeqNum() + 1);
				// 余额=上一条余额-将要被冻结的金额
				ib.setBalance(ArithUtil.sub(ibLastest.getBalance(), money));
				// 最新冻结金额=上一条冻结+将要冻结
				ib.setFrozenMoney(ArithUtil.add(ibLastest.getFrozenMoney(),
						money));
			}
			bt.add(ib);
		}
	}

	private double getSumByType(String userId, String type) {
		Map<String, Object> sqlMap = bt
				.queryMap("select sum(ub.money) countNum from UserBill ub where ub.user.id ='"
						+ userId + "' and ub.type='" + type + "'");
		if (sqlMap == null) {
			return 0;
		}
		return ArithUtil.round(
				Double.parseDouble(sqlMap.get("countNum").toString()), 2);
	}

	public JSONObject repayProfit(JSONObject json, String value) {
		Map<String, String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		Object pageSize = param.get("pageSize");
		Object currentPage = param.get("currentPage");
		ParamUtil.notNullParam("用户名:" + userId, "页大小:" + pageSize,
				"当前页:" + currentPage);
		String sql = "select ir.* from INVEST_REPAY ir INNER JOIN invest inv on ir.invest_id = inv.id where inv.user_id ='"
				+ userId + "' and ir.`status` = 'complete'";
		List<InvestRepayBase> listBean = bt.queryListBean(sql,
				InvestRepayBase.class);
		List<AppProfit> appList = new ArrayList<AppProfit>();
		AppProfit profit = null;
		for (InvestRepayBase ir : listBean) {
			LoanBase loan = bt
					.queryBean(
							"SELECT lo.* FROM LOAN lo LEFT JOIN INVEST inv ON lo.ID = inv.LOAN_ID WHERE inv.ID='"
									+ ir.getInvestId() + "'", LoanBase.class);
			profit = new AppProfit();
			profit.setCorpus(Double.parseDouble(ir.getCorpus()));
			profit.setDeadline(loan.getDeadline());
			profit.setInterest(Double.parseDouble(ir.getInterest()));
			profit.setPeriod(ir.getPeriod());
			profit.setUsername(userId);
			profit.setRate(ArithUtil.round(loan.getRate() * 100, 2) + "%");
			appList.add(profit);
		}
		json.put("result", appList);
		return json;
	}

	public JSONObject investProfit(JSONObject json, String value) {
		@SuppressWarnings("unchecked")
		Map<String, String> param = JSON.parseObject(value, HashMap.class);
		Object userIdO = param.get("userId");
		Object pageSize = param.get("pageSize");
		Object currentPage = param.get("currentPage");
		if (userIdO == null || pageSize == null || currentPage == null) {
			json.put("status", 500);
			json.put("msg", "参数异常");
			return json;
		}
		List<Map<String, Object>> listMap = rinvestMapper
				.investByUserStatusLoan(param);
		List<AppProfit> appList = new ArrayList<AppProfit>();
		AppProfit profit = null;
		for (Map<String, Object> map : listMap) {
			profit = new AppProfit();
			profit.setDeadline(map.get("DEADLINE").toString());
			profit.setUsername(userIdO.toString());
			profit.setRate(ArithUtil.round(
					Double.parseDouble(map.get("RATE").toString()) * 100, 2)
					+ "%");
			appList.add(profit);
		}
		json.put("result", appList);
		return json;
	}

	/**
	 * 交易记录
	 * 
	 * @author wtj
	 * @date 2015年12月10日下午3:04:07
	 * @param json
	 * @param value
	 * @throws InstantiationException
	 * @throws IllegalAccessException
	 */
	public JSONObject transactionRecords(JSONObject json, String value) {
		@SuppressWarnings("unchecked")
		Map<String, Object> param = JSON.parseObject(value, HashMap.class);
		Object userIdO = param.get("userId");
		/**
		 * String typeInfo = param.get("typeInfo"); recharge_success 充值成功
		 * invest_success 投资成功 withdraw_success 体现成功 admin_operation 管理员干预
		 * 
		 * 还款 repay_success normal_repay advance_repay overdue_repay
		 */
		/**
		 * String queryDateType = param.get("queryDateType"); one_up 一个月以上
		 * three_up 三个月以上 three_six 三到六个月 six_twelve 6-12个月 twelve_up 12月以上
		 */
		Object pageSize = param.get("pageSize");
		Object currentPage = param.get("currentPage");
		if (userIdO == null) {
			json.put("status", 500);
			json.put("msg", "用户ID不能为空");
			return json;
		}
		param.put("page", PageUtil.getTagPage(currentPage.toString(),pageSize.toString()));
		List<Map<String, Object>> listMap = rmyAccountMapper.rechargeListPage(param);
		List<UserBillBase> listBean = BUtils.tableListMapToBean(listMap,
				UserBillBase.class);
		for (UserBillBase bean : listBean) {
			DictBase dict = bt.queryBean("dict", "id", bean.getTypeInfo(),DictBase.class);
			if(dict==null){
				bean.setTypeInfo(bean.getTypeInfo());
			}else{
				bean.setTypeInfo(dict.getValue());
			}
		}
		json.put("result", listBean.size()==0?new String[]{}:listBean);
		return json;
	}

	public static Map<String,String> getInfoType(){
		Map<String,String> map = new HashMap<String,String>();
		// 回款的情况
		map.put("投资流标", "normal_repay");
		map.put("正常还款", "normal_repay");
		map.put("借款流标", "normal_repay");
		map.put("normal_repay", "normal_repay");
		map.put("cancel_invest", "normal_repay");
		
		// 投资成功
		map.put("投资成功", "invest_success");
		map.put("invest_success", "invest_success");
		
		// 提现成功
		map.put("withdraw_success", "withdraw_success");
		map.put("提现成功", "withdraw_success");
		
		// 充值
		map.put("recharge_success", "recharge_success");
		map.put("充值成功", "充值成功");
		
		
		
		return map;
	}
	/**
	 * 充值
	 * 
	 * @author wtj
	 * @date 2015年12月11日上午10:26:38
	 * @param json
	 * @param value
	 * @return
	 */
	public JSONObject recharge(JSONObject json, String value) {
		Map<String, String> para = MapUtil.jsonToMapString(value);
		String userId = para.get("userId");
		String money = para.get("money");
		ParamUtil.notNullParam("用户名:" + userId, "充值金额:" + money);

		Double actualMoney = Double.parseDouble(money);// 真实金额
		UserBase user = beanService.getUserById(userId);
		if (user == null) {
			json.put("status", 500);
			json.put("msg", "用户不存在");
			return json;
		}
		RechargeBase recharge = new RechargeBase();
		recharge.setUserId(userId);
		recharge.setActualMoney(actualMoney);
		recharge.setFee(0.0);
		recharge.setRechargeWay("yeepay");
		// 保存一个充值订单
		rechargeService.createRechargeOrder(recharge);
		String reqContent = getReqParams(recharge);
		String sign = CFCASignUtil.sign(reqContent);
		// 包装参数
		Map<String, String> params = new HashMap<String, String>();
		params.put("req", reqContent);
		params.put("sign", sign);
		TrusteeshipOperationBase to = new TrusteeshipOperationBase();
		to.setId(IdGenerator.randomUUID());
		to.setMarkId(recharge.getId());
		to.setOperator(recharge.getId());
		to.setRequestTime(new Date());
		to.setRequestUrl(AppConstants.RequestUrl.APP_RECHARGE_URL);
		to.setStatus(TrusteeshipConstants.Status.SENDED);
		to.setType(YeePayConstants.OperationType.RECHARGE);
		to.setTrusteeship("yeepay");
//		bt.add(to);
		
		String result = HtmlElementUtil.createAutoSubmitForm(params,AppConstants.RequestUrl.APP_RECHARGE_URL, "UTF-8");
		to.setRequestData(result);
		rmyAccountMapper.addTrusteeshipOperation(to);

		Map<String,Object> mapHtml = new HashMap<String,Object>();
		mapHtml.put("sign", sign);
		// 是否拦截  true:拦截  false:不拦截
		mapHtml.put("isIntercept", "true");
		mapHtml.put("reqContent", reqContent);
		mapHtml.put("actionUrl", AppConstants.RequestUrl.APP_RECHARGE_URL);
		mapHtml.put("callbackUrl", 	AppConstants.ResponseWebUrl.PRE_RESPONSE_URL+ YeePayConstants.OperationType.RECHARGE );
		json.put("result", mapHtml);
//		json.put("result", result);
		return json;
	}

	/**
	 * 充值获取易宝支付信息
	 * @author wtj
	 * @date 2015年12月11日下午4:25:11
	 * @param recharge
	 * @return
	 */
	private String getReqParams(RechargeBase recharge) {
		StringBuilder content = new StringBuilder();
		content.append("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>");
		content.append("<request platformNo='"
				+ YeePayConstants.Config.MER_CODE + "'>");
		content.append("<platformUserNo>" + recharge.getUserId()
				+ "</platformUserNo>");
		content.append("<requestNo>" + YeePayConstants.RequestNoPre.RECHARGE
				+ recharge.getId() + "</requestNo>");
		content.append("<amount>" + recharge.getActualMoney() + "</amount>");
		// 谁付手续费 1：平台支付 2：用户支付
		String feeType = this.getConfigValue("yeepay.recharge_fee_type");
		if ("2".equals(feeType)) {
			content.append("<feeMode>" + "USER" + "</feeMode>");
		} else {
			content.append("<feeMode>" + "PLATFORM" + "</feeMode>");
		}

//		/* 正确的URL */
		content.append("<callbackUrl>"
				+ AppConstants.ResponseWebUrl.PRE_RESPONSE_URL
				+ YeePayConstants.OperationType.RECHARGE 
				+ "</callbackUrl>");
		/* 服务器通知 URL */
		content.append("<notifyUrl>"
				+ AppConstants.ResponseS2SUrl.PRE_RESPONSE_URL
				+ YeePayConstants.OperationType.RECHARGE 
				+ "</notifyUrl>");

//		/* 错误的URL */
//		content.append("<callbackUrl>"
//		+ AppConstants.ResponseS2SUrl.PRE_RESPONSE_URL
//		+ YeePayConstants.OperationType.RECHARGE 
//		+ "</callbackUrl>");
//		/* 服务器通知 URL */
//		content.append("<notifyUrl>"
//		+ AppConstants.ResponseWebUrl.PRE_RESPONSE_URL
//		+ YeePayConstants.OperationType.RECHARGE 
//		+ "</notifyUrl>");
		
		content.append("</request>");

		return content.toString();
	}
	
	/**
	 * 用户提现
	 * @author wtj
	 * @date 2015年12月11日下午3:14:27
	 * @param json
	 * @param value
	 * @return
	 */
	@Transactional(propagation = Propagation.REQUIRED)
	public JSONObject withdraw(JSONObject json,String value){
		Map<String,String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		String moneyStr = param.get("money");
		// 加急 URGENT
		String withdrawType = param.get("withdrawType");
		ParamUtil.notNullParam("用户名:"+userId,"提现金额:"+moneyStr);
		UserBase user = beanService.getUserById(userId);
		if(user == null){
			json.put("status",500);
			json.put("msg","用户不存在");
			return json;
		}
		Double money = Double.parseDouble(moneyStr);
		double withdrawFee = withdrawCashService.calculateFee(money,withdrawType);
		if ((money+withdrawFee) > this.getUserBalance(userId)) {
			json.put("status",500);
			json.put("msg","账户金额不足");
			return json;
		}
//		List<BankCardBase> listBean = bt.queryListBean("BANK_CARD", new String[]{"user_id","status"}, new Object[]{userId, "VERIFIED"}, BankCardBase.class);
		List<BankCardBase> listBean = bt.queryListBean("select * from BANK_CARD where user_id='"+userId+"' and status != '已删除'" , BankCardBase.class);
		if(listBean == null || listBean.size() == 0){
			json.put("status",500);
			json.put("msg","未绑定提现银行卡");
			return json;
		}
		BankCardBase bankCard = listBean.get(0);
		//创建提现订单
		WithdrawCashBase cash=new WithdrawCashBase();
		cash.setUserId(userId);;
		cash.setBankCardId(bankCard.getId());
		cash.setMoney(money);
		cash.setFee(withdrawFee);

		withdrawCashService.applyWithdrawCash(cash);
		
		//处理请求参数
		String reqContent = getTXReqParams(cash,withdrawType);
		String sign = CFCASignUtil.sign(reqContent);

		// 包装参数
		Map<String, String> params = new HashMap<String, String>();
		params.put("req", reqContent);
		params.put("sign", sign);
		
		String withdrawUrl = AppConstants.RequestUrl.APP_WITHDRAW_URL;
		if(withdrawType!=null && withdrawType.equals("URGENT")){
			withdrawUrl = withdrawUrl.replace("bhawireless","bha");
		}
		TrusteeshipOperationBase to = new TrusteeshipOperationBase();
		to.setId(IdGenerator.randomUUID());
		// 用来查询一条提现记录
		to.setMarkId(cash.getId());
		to.setOperator(cash.getId());
		to.setRequestTime(new Date());
		to.setRequestUrl(withdrawUrl);
		String result = HtmlElementUtil.createAutoSubmitForm(params,withdrawUrl, "UTF-8");
		to.setRequestData(result);
		to.setStatus(TrusteeshipConstants.Status.SENDED);
		to.setType(YeePayConstants.OperationType.WITHDRAW_CASH);
		to.setTrusteeship("yeepay");
		rmyAccountMapper.addTrusteeshipOperation(to);
		Map<String,Object> mapHtml = new HashMap<String,Object>();
		mapHtml.put("iconUrl", MessageFormat.format(AppConstants.PublicConstants.BANK_CARD_URL, YeePayParams.getBankCode(bankCard.getBankNo(),bankCard.getBank())));
		mapHtml.put("sign", sign);
		if(withdrawType.equals("1") || withdrawType.equals("URGENT")){
			mapHtml.put("isIntercept", Constants.IS_INTERCEPT_FALSE);
		}else{
			mapHtml.put("isIntercept", Constants.IS_INTERCEPT_TRUE);	
		}
		mapHtml.put("reqContent", reqContent);
		mapHtml.put("actionUrl", withdrawUrl);
		mapHtml.put("callbackUrl", 	AppConstants.ResponseWebUrl.PRE_RESPONSE_URL+ YeePayConstants.OperationType.WITHDRAW_CASH );
		json.put("result", mapHtml);
		return json;
	};
	
	public String getConfigValue(String configId) {
		ConfigBase bean = bt.queryBean("CONFIG", "ID", configId, ConfigBase.class);
		if (bean != null) {
			return bean.getValue();
		}
		throw new CxdException( "config ID:"+ configId + "对象为空！");
	}
	
	/**
	 * 用户提现 返回易宝支付信息
	 * @author wtj
	 * @date 2015年12月11日下午4:00:02
	 * @param cash
	 * @return
	 */
	private String getTXReqParams(WithdrawCashBase cash,String withdrawType){
		StringBuilder content = new StringBuilder();
		content.append("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>");
		// 商户编号:商户在易宝唯一标识
		content.append("<request platformNo='"+ YeePayConstants.Config.MER_CODE + "'>");
		// 商户平台会员标识:会员在商户平台唯一标识
		content.append("<platformUserNo>" + cash.getUserId()+ "</platformUserNo>");
		// 请求流水号:接入方必须保证参数内的 requestNo 全局唯一，并且需要保存，留待后续业务使用
		content.append("<requestNo>"+YeePayConstants.RequestNoPre.WITHDRAW_CASH + cash.getId() + "</requestNo>");
		// 费率模式:见费率模式
		// yee手续费收取方:1：平台支付 2：提现方支付
		String feeType = this.getConfigValue("yeepay.withdraw_fee_type");
		// 平台手续费
		if (feeType.equals("1")) {
			content.append("<feeMode>" + "PLATFORM" + "</feeMode>");
		} else {
			// 如果是用户自己承担手续费，假如提现100，手续费3块，则账户扣除103
			content.append("<feeMode>" + "USER" + "</feeMode>");
		}
		if(withdrawType!=null && withdrawType.equals("URGENT")){
			content.append("<withdrawType>URGENT</withdrawType>");
		}
		content.append("<callbackUrl>"
				+ AppConstants.ResponseWebUrl.PRE_RESPONSE_URL
				+ YeePayConstants.OperationType.WITHDRAW_CASH
				+ "</callbackUrl>");
		/* 服务器通知 URL:服务器通知 URL */
		content.append("<notifyUrl>"
				+ AppConstants.ResponseS2SUrl.PRE_RESPONSE_URL
				+ YeePayConstants.OperationType.WITHDRAW_CASH 
				+ "</notifyUrl>");
		// 提现金额:如果传入此，将使用该金额提现且用户将不可更改
		content.append("<amount>" + cash.getMoney() + "</amount>");
		content.append("</request>");
		return content.toString();
	}
	
	/**
	 * 解绑 
	 * @author wtj
	 * @date 2016年1月10日下午5:33:54
	 * @param json
	 * @param value
	 * @return
	 */
	public JSONObject unCardBind(JSONObject json, String value) {
		Map<String,String> retResMap = new HashMap<String,String>();
		Map<String, String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		ParamUtil.notNullParam("用户名:"+userId);
		String msg = "未找到银行卡信息";
		BankCardBase bankCardBean = bt.queryBean("select * from BANK_CARD bc where bc.user_id='"+userId+"' and bc.status='VERIFIED' limit 0,1", BankCardBase.class);
		if(bankCardBean==null || StringUtils.isBlank(bankCardBean.getId())){
			json.put("status", 500);
			json.put("msg",msg);
			return json;
		}
		// 查看易宝用户信息 易宝没有用户的绑卡信息
		Map<String,Object> map = this.queryYeePayUserInfo(userId);
		Object code1 = map.get("code");
		if(code1==null){
			json.put("status", 500);
			json.put("msg", "用户数据查询异常");
			retResMap.put("status", json.get("msg").toString());
			json.put("result", retResMap);
			return json;
		}
		if(!code1.equals("1")){
			json.put("status", 500);
			json.put("msg",map.get("description"));
			retResMap.put("status", json.get("msg").toString());
			json.put("result", retResMap);
			return json;
		}
		Object cardNo = map.get("cardNo");
		if(cardNo==null || StringUtils.isBlank(cardNo.toString())){
			bankCardBean.setStatus("已删除");
			bt.modify(bankCardBean);
			json.put("status", 200);
			json.put("msg", msg);
			retResMap.put("status", json.get("msg").toString());
			json.put("result",retResMap);
			return json;
		}
		TrusteeshipOperationBase to = new TrusteeshipOperationBase();
		HttpClient client = new HttpClient();
		// 创建一个post方法
		PostMethod postMethod = new PostMethod(YeePayConstants.RequestUrl.RequestDirectUrl);
		postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
		StringBuffer content = new StringBuffer();
		content.append("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>");
		content.append("<request platformNo='"+ YeePayConstants.Config.MER_CODE + "'>");
		content.append("	<platformUserNo>" +userId+ "</platformUserNo>");
		content.append("	<requestNo>" +  IdGenerator.randomUUID()+ "</requestNo>");
		content.append("</request>");
		// 生成密文
		String sign = CFCASignUtil.sign(content.toString());
		postMethod.setParameter("req", content.toString());
		postMethod.setParameter("sign", sign);
		postMethod.setParameter("service", "UNBIND_CARD");
		// 执行post方法
		try {
			client.executeMethod(postMethod);
			/* 处理返回信息 */
			byte[] responseBody = postMethod.getResponseBody();
			log.debug(new String(responseBody, "UTF-8"));
			// 响应信息
			Map<String, String> resultMap = Dom4jUtil.xmltoMap(new String(responseBody, "UTF-8"));
			
			String code = resultMap.get("code");
			msg = resultMap.get("description");
			log.debug(new String(responseBody, "UTF-8"));
			
			if ("1".equals(code) || "101".equals(code)) {
				// 未升级快捷支付
				if(map.get("paySwift").equals("NORMAL")){
					bankCardBean.setStatus("已删除");
					to.setStatus(TrusteeshipConstants.Status.PASSED);
					msg = "解绑成功";
				}
				// 已升级快捷支付
				else{
					bankCardBean.setStatus("解绑审核中");
					to.setStatus(TrusteeshipConstants.Status.UN_CARD_ING);
					msg = "解绑审核中（最长两个工作日，请耐心等待）";
				}
				to.setId(IdGenerator.randomUUID());
				to.setMarkId(userId);
				to.setOperator(userId);
				to.setResponseData(new String(responseBody, "UTF-8"));
				to.setResponseTime(new Date());
				to.setRequestTime(new Date());
				to.setRequestData("req="+content.toString()+"sign="+sign);
				to.setType(YeePayConstants.OperationType.UNBINDING_YEEPAY_BANKCARD);
				rmyAccountMapper.addTrusteeshipOperation(to);
				// bt.modify(to);
				bt.modify(bankCardBean);
				json.put("status", 200);
				json.put("msg",msg);
				retResMap.put("status", msg);
				json.put("result", retResMap);
			} else {
				json.put("status", 500);
				json.put("msg",msg);
				retResMap.put("status", json.get("msg").toString());
				json.put("result", retResMap);
				// 操作失败是不执行操作 避免unknowHost异常
				log.debug(new String(responseBody, "UTF-8"));
			}
		} catch (HttpException e) {
			json.put("status", 500);
			json.put("msg","易宝网络错误");
			retResMap.put("status", json.get("msg").toString());
			json.put("result", retResMap);
			log.error("Fatal protocol violation: " + e.getMessage());
		} catch (IOException e) {
			json.put("status", 500);
			json.put("msg","数据解析错误");
			retResMap.put("status", json.get("msg").toString());
			json.put("result", retResMap);
			log.error("Fatal transport error: " + e.getMessage());
		}  finally {
			postMethod.releaseConnection();
		}
		return json;
	}
	
	/**
	 * 绑定银行卡
	 * @author wtj
	 * @date 2015年12月14日上午10:27:51
	 * @param json
	 * @param value
	 * @return
	 */
	public JSONObject bindBankCard(JSONObject json,String value){
		Map<String, String> param = MapUtil.jsonToMapString(value);
		String userId = param.get("userId");
		ParamUtil.notNullParam("用户名:"+userId);
		// 创建绑卡订单
		BankCardBase bc = new BankCardBase();
		bc.setStatus("VERIFYING"); //认证中
		bc.setId(IdGenerator.randomUUID());
		bc.setBank(rechargeService.getBankNameByNo(bc.getBankNo()));
		bc.setTime(new Date());
		bc.setUserId(userId);
		
		// 签名并组装参数
		String reqContent = YeePayParams.bindBankCardParams(bc);
		String sign = CFCASignUtil.sign(reqContent);
		Map<String, String> params = new HashMap<String, String>();
		params.put("req", reqContent);
		params.put("sign", sign);
		
		// 操作记录
		TrusteeshipOperationBase to = new TrusteeshipOperationBase();
		to.setId(IdGenerator.randomUUID());
		to.setMarkId(userId);
		to.setOperator(userId);
		to.setRequestTime(new Date());
		to.setRequestUrl(AppConstants.RequestUrl.APP_BINDCARD_URL);
		to.setRequestData(MapUtil.mapToString(params));
		to.setStatus(TrusteeshipConstants.Status.SENDED);
		to.setType(YeePayConstants.OperationType.BINDING_YEEPAY_BANKCARD);
		to.setTrusteeship("yeepay");
		bt.add(to);
		
		Map<String,Object> mapHtml = new HashMap<String,Object>();
		mapHtml.put("sign", sign);
		mapHtml.put("isIntercept", "true");
		mapHtml.put("reqContent", reqContent);
		mapHtml.put("actionUrl", AppConstants.RequestUrl.APP_BINDCARD_URL);
		mapHtml.put("callbackUrl", AppConstants.ResponseWebUrl.PRE_RESPONSE_URL+ YeePayConstants.OperationType.BINDING_YEEPAY_BANKCARD);
		json.put("result", mapHtml);
		return json;
	}
	

	/**
	 * 应收（待收）利息
	 * 
	 * @return
	 */
	public double getReceivableInterest(String userId) {
		String sql = "SELECT sum(ir.interest+default_interest-ir.fee) as countNum FROM INVEST_REPAY ir INNER JOIN INVEST inv on ir.INVEST_ID = inv.ID WHERE  ir.time is null and inv.USER_ID='"+userId+"' and inv.`status` ='repaying'";
		List<Map<String,Object>> result = bt.queryListMap(sql);
		double money = 0;
		if (result != null && result.get(0) != null) {
			money = (Double) result.get(0).get("countNum");
		}
		return money;
	}
	/**
	 * 已收利息
	 * 
	 * @return
	 */
	public double getReceivedInterest(String userId) {
		String sql = "SELECT sum(ir.interest+ir.default_interest-ir.fee) as countNum FROM INVEST_REPAY ir INNER JOIN INVEST inv on ir.INVEST_ID = inv.ID WHERE ir.time is not null and inv.USER_ID ='"+userId+"' and ir.time <= now()";
		List<Map<String,Object>> result = bt.queryListMap(sql);
		double money = 0;
		if (result != null && result.get(0) != null) {
			money = (Double) result.get(0).get("countNum");
		}
		return money;
	}
	
	/**
	 * 已收本金
	 * 
	 * @return
	 */
	public double getReceivedCorpus(String userId) {
		// InvestRepay
		String sql = "SELECT sum(corpus) as countNum FROM INVEST_REPAY ir INNER JOIN INVEST inv on ir.INVEST_ID = inv.ID WHERE ir.time is not null and inv.USER_ID = '"+userId+"' and ir.time <= now() ";
		List<Map<String,Object>> result = bt.queryListMap(sql);
		double money = 0;
		if (result != null && result.get(0) != null) {
			money = (Double) result.get(0).get("countNum");
		}
		return money;
	}
	
	/**
	 * 查询易宝用户信息
	 * @author wtj
	 * @date 2015年12月24日下午1:38:11
	 * @param platformUserNo
	 * @return
	 */
	public Map<String,Object> queryYeePayUserInfo(String platformUserNo){
		Map<String,Object> reMap = new HashMap<String,Object>();
		HttpClient client = new HttpClient();
		// 创建一个post方法
		PostMethod postMethod = new PostMethod(YeePayConstants.RequestUrl.RequestDirectUrl);
		postMethod.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "utf-8");
		StringBuffer content = new StringBuffer();
		content.append("<?xml version='1.0' encoding='UTF-8' standalone='yes'?>");
		content.append("<request platformNo='"+ YeePayConstants.Config.MER_CODE + "'>");
		content.append("<platformUserNo>" + platformUserNo+ "</platformUserNo>");
		content.append("</request>");
		// 生成密文
		String sign = CFCASignUtil.sign(content.toString());

		postMethod.setParameter("req", content.toString());
		postMethod.setParameter("sign", sign);
		postMethod.setParameter("service", "ACCOUNT_INFO");

		// 执行post方法
		try {
			int statusCode = client.executeMethod(postMethod);

			byte[] responseBody = postMethod.getResponseBody();
			log.debug(new String(responseBody, "UTF-8"));
			// 响应信息
			Map<String, String> resultMap = Dom4jUtil.xmltoMap(new String(responseBody, "UTF-8"));
			String code = resultMap.get("code");
			if (code.equals("1")) {
				
				String platformNo = resultMap.get("platformNo");
				String description = resultMap.get("description");
				// 【见会员类型】
				String memberType = resultMap.get("memberType");
				// 【见会员激活状态】
				String activeStatus = resultMap.get("activeStatus");
				// 账户余额
				String balance = resultMap.get("balance");
				// 可用余额
				String availableAmount = resultMap.get("availableAmount");
				// 冻结金额
				String freezeAmount = resultMap.get("freezeAmount");
				// 绑定的卡号,没有则表示没有绑卡
				String cardNo = resultMap.get("cardNo");
				String cardStatus = resultMap.get("cardStatus");
				String bank = resultMap.get("bank");
				// 是否已授权自动投标,true 或则false
				String autoTender = resultMap.get("autoTender");
				// 表示用户是否已开通快捷支付。NORMAL 表示未升级，UPGRADE 表示已升级
				String paySwift = resultMap.get("paySwift");
				String bindMobileNo = resultMap.get("bindMobileNo");
				reMap.put("platformNo", platformNo);
				reMap.put("code", code);
				reMap.put("description", description);
				reMap.put("memberType", memberType);
				reMap.put("activeStatus", activeStatus);
				reMap.put("balance", balance);
				reMap.put("availableAmount", availableAmount);
				reMap.put("freezeAmount", freezeAmount);
				reMap.put("cardNo", cardNo);
				reMap.put("cardStatus", cardStatus);
				reMap.put("bank", bank);
				reMap.put("autoTender", autoTender);
				reMap.put("paySwift", paySwift);
				reMap.put("bindMobileNo", bindMobileNo);
			} else{
				String description = resultMap.get("description");
				reMap.put("description", description);
			}
		} catch (HttpException e) {
			log.error("Fatal protocol violation: " + e.getMessage());
			e.printStackTrace();
		} catch (IOException e) {
			log.error("Fatal transport error: " + e.getMessage());
			e.printStackTrace();
		} finally {
			postMethod.releaseConnection();
		}
		return reMap;
	}
}
